<!--
 * @Author: Bobby
 * @Date: 2022-01-09 05:15:41
 * @LastEditTime: 2022-03-04 11:33:53
 * @LastEditors: Bobby
 * @Description:
 * @FilePath: \wms-v2\src\vui\components\VuiUpload\index.vue
 * CIMC-V2
-->
<template>
  <div class="vui-upload">
    <el-upload
      ref="upload"
      :accept="accept"
      :action="url"
      :auto-upload="autoUpload"
      :before-upload="beforeUpload"
      :data="encryptdData"
      :file-list="fileListData"
      :headers="headersData"
      :limit="limit"
      :list-type="listType"
      :multiple="multiple"
      :name="fileName"
      :on-change="handleChange"
      :on-error="handleError"
      :on-exceed="handleExceed"
      :on-preview="handlePreview"
      :on-progress="handleProgress"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :show-file-list="showFileList"
    >
      <slot></slot>
      <template #file="{ file }" v-if="listType == 'picture-card'">
        <div>
          <img alt="" class="el-upload-list__item-thumbnail" :src="file.url" />
          <span class="el-upload-list__item-actions">
            <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
              <vui-icon icon="zoom-in-line" />
            </span>
            <span class="el-upload-list__item-delete" @click="handlePreview(file)">
              <vui-icon icon="download-line" />
            </span>
            <span class="el-upload-list__item-delete" @click="handleRemove(file)">
              <vui-icon icon="delete-bin-line" />
            </span>
          </span>
        </div>
      </template>
    </el-upload>
  </div>
</template>

<script>
  import { defineComponent } from 'vue'
  import { mapGetters } from 'vuex'
  import round from 'lodash/round'
  import { encryptd, decryptd } from '@/utils/tools'
  import { requestEncryptd } from '@project/config'

  export default defineComponent({
    name: 'VuiUpload',
    props: {
      // 请求url
      url: {
        type: String,
        default: '/upload',
        required: true,
      },
      //自动上传
      autoUpload: {
        type: Boolean,
        default: false,
      },
      showFileList: {
        type: Boolean,
        default: true,
      },
      //是否支持多文件
      multiple: {
        type: Boolean,
        default: true,
      },
      //提交file name
      fileName: {
        type: String,
        default: 'file',
        required: true,
      },
      //最多上传限制
      limit: {
        type: Number,
        default: 10,
        required: true,
      },
      //最大x(MB)
      size: {
        type: Number,
        default: 1,
      },
      //类别类型
      listType: {
        type: String,
        default: 'text',
      },
      //文件格式限制
      accept: {
        type: String,
        default: '*',
      },
      //额外参数
      postData: {
        type: Object,
        default: () => {},
      },
      //额外header
      headers: {
        type: Object,
        default: () => {},
      },
      //fileList
      fileList: {
        type: Array,
        default: () => [],
      },
      fileNum: {
        type: Number,
        default: 1,
      },
    },
    emits: ['uploadSuccess', 'beforeUpload', 'handlePreview', 'handleRemove', 'handlePictureCardPreview'],
    data() {
      return {
        loading: false,
        imgNum: 0,
        imgSuccessNum: 0,
        imgErrorNum: 0,
      }
    },
    computed: {
      ...mapGetters({
        token: 'user/token',
      }),
      percentage() {
        if (this.allImgNum === 0) return 0
        return round(this.imgNum / this.allImgNum, 2) * 100
      },
      encryptdData() {
        if (requestEncryptd) {
          return { ...this.postData, data: encryptd(this.postData.data) }
        } else {
          return this.postData
        }
      },
      headersData() {
        return {
          token: this.token,
          ...this.headers,
        }
      },
      fileListData() {
        return this.fileList
      },
    },
    watch: {
      fileNum(val) {
        if (val == 0) {
          this.imgNum = val
        }
      },
    },
    created() {},
    methods: {
      reset() {
        this.allImgNum = 0
        this.imgNum = 0
        this.imgSuccessNum = 0
        this.imgErrorNum = 0
      },
      handlePictureCardPreview(file) {
        console.log(file)
        this.$emit('handlePictureCardPreview', file)
      },
      beforeUpload() {
        this.$emit('beforeUpload')
      },
      submitUpload() {
        this.$refs.upload.submit()
      },
      handleProgress() {
        this.loading = true
      },
      handleChange(file, fileList) {
        if (file.size > 20971520 * this.size) {
          fileList.filter((item) => item !== file)
          this.fileListData = fileList
        } else {
          this.allImgNum = fileList.length
        }
      },
      handleSuccess(response, file, fileList) {
        this.imgNum = this.imgNum + 1
        this.imgSuccessNum = this.imgSuccessNum + 1
        // if (fileList.length === this.imgNum) {
        let obj = {
          fileList,
          response: '',
          file,
        }
        if (requestEncryptd) {
          obj.response = JSON.parse(decryptd(decodeURIComponent(response)))
          fileList.forEach((r) => {
            r.response = JSON.parse(decryptd(decodeURIComponent(response)))
          })
        } else {
          obj.response = response
        }
        this.$emit('uploadSuccess', obj)
        // }
        setTimeout(() => {
          this.loading = false
        }, 1000)
      },
      handleError(err, file) {
        // this.imgNum = this.imgNum + 1
        this.imgErrorNum = this.imgErrorNum + 1
        this.$baseMessage(`文件[${file.raw.name}]上传失败,文件大小为${round(file.raw.size / 1024, 0)}KB`, 'error', 'vui-hey-message-error')
        setTimeout(() => {
          this.loading = false
        }, 1000)
      },
      handlePreview(uploadFile) {
        this.$emit('handlePreview', uploadFile)
      },
      handleRemove(uploadFile, uploadFiles) {
        if (this.imgNum > 0) this.imgNum = this.imgNum - 1
        this.allNum = this.allNum - 1
        this.$emit('handleRemove', { uploadFile, uploadFiles })
      },
      handleExceed(files) {
        this.$baseMessage(
          `当前限制选择 ${this.limit} 个文件，本次选择了
               ${files.length}
               个文件`,
          'error',
          'vui-hey-message-error'
        )
      },
    },
  })
</script>
<style lang="scss">
  .vui-upload > div {
    width: 100%;
    height: 100%;
  }
  .el-upload {
    text-align: left;
  }
</style>
